/*
 * Copyright (c) 2011-2014, Peter Abeles. All Rights Reserved.
 *
 * This file is part of BoofCV (http://boofcv.org).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package boofcv.struct.convolve;

import boofcv.misc.AutoTypeImage;
import boofcv.misc.CodeGeneratorBase;

import java.io.FileNotFoundException;

/**
 * @author Peter Abeles
 */
public class GenerateKernel1D extends CodeGeneratorBase {
	@Override
	public void generate() throws FileNotFoundException {
		createFile(AutoTypeImage.F32);
		createFile(AutoTypeImage.F64);
		createFile(AutoTypeImage.S32);
	}

	private void createFile( AutoTypeImage imageType ) throws FileNotFoundException  {
		String suffix = imageType.getAbbreviatedType();
		suffix = suffix.compareTo("S32") == 0 ? "I32" : suffix;
		className = "Kernel1D_"+suffix;

		String sumType = imageType.getSumType();

		setOutputFile(className);
		out.print("/**\n" +
				" * Floating point 1D convolution kernel that extends {@link Kernel1D}.\n" +
				" *\n" +
				" * <p>\n" +
				" * WARNING: Do not modify.  Automatically generated by {@link "+getClass().getName()+"}.\n" +
				" * </p>\n" +
				" *\n" +
				" * @author Peter Abeles\n" +
				" */\n" +
				"public class "+className+" extends Kernel1D {\n" +
				"\n" +
				"\tpublic "+sumType+" data[];\n" +
				"\n" +
				"\t/**\n" +
				"\t * Creates a new kernel whose initial values are specified by data and width.  The length\n" +
				"\t * of its internal data will be width.  Data must be at least as long as width.\n" +
				"\t *\n" +
				"\t * @param data  The value of the kernel. Not modified.  Reference is not saved.\n" +
				"\t * @param width The kernels width.  Must be odd.\n" +
				"\t */\n" +
				"\tpublic "+className+"("+sumType+" data[], int width) {\n" +
				"\t\tthis(data,width/2,width);\n" +
				"\t}\n" +
				"\n" +
				"\t/**\n" +
				"\t * Creates a new kernel whose initial values are specified by data and width.  The length\n" +
				"\t * of its internal data will be width.  Data must be at least as long as width.\n" +
				"\t *\n" +
				"\t * @param data  The value of the kernel. Not modified.  Reference is not saved.\n" +
				"\t * @param width The kernels width.  Must be odd.\n" +
				"\t * @param offset Location of the origin in the array\n" +
				"\t */\n" +
				"\tpublic "+className+"("+sumType+" data[], int offset , int width) {\n" +
				"\t\tsuper(offset,width);\n" +
				"\n" +
				"\t\tthis.data = new "+sumType+"[width];\n" +
				"\t\tSystem.arraycopy(data, 0, this.data, 0, width);\n" +
				"\t}\n" +
				"\n" +
				"\t/**\n" +
				"\t * Create a kernel whose elements are all equal to zero.\n" +
				"\t *\n" +
				"\t * @param width How wide the kernel is.  Must be odd.\n" +
				"\t */\n" +
				"\tpublic "+className+"(int width) {\n" +
				"\t\tthis(width/2,width);\n" +
				"\t}\n" +
				"\n" +
				"\t/**\n" +
				"\t * Create a kernel whose elements are all equal to zero.\n" +
				"\t *\n" +
				"\t * @param width How wide the kernel is.  Must be odd.\n" +
				"\t * @param offset Location of the origin in the array\n" +
				"\t */\n" +
				"\tpublic "+className+"(int offset , int width) {\n" +
				"\t\tsuper(offset,width);\n" +
				"\t\tdata = new "+sumType+"[width];\n" +
				"\t}\n" +
				"\n" +
				"\tprotected "+className+"() {\n" +
				"\t}\n" +
				"\n" +
				"\t/**\n" +
				"\t * Creates a kernel whose elements are the specified data array and has\n" +
				"\t * the specified width.\n" +
				"\t *\n" +
				"\t * @param data  The array who will be the kernel's data.  Reference is saved.\n" +
				"\t * @param width The kernel's width.\n" +
				"\t * @return A new kernel.\n" +
				"\t */\n" +
				"\tpublic static "+className+" wrap("+sumType+" data[], int width) {\n" +
				"\t\t"+className+" ret = new "+className+"();\n" +
				"\t\tret.data = data;\n" +
				"\t\tret.width = width;\n" +
				"\t\tret.offset = width/2;\n" +
				"\n" +
				"\t\treturn ret;\n" +
				"\t}\n" +
				"\n" +
				"\t@Override\n" +
				"\tpublic boolean isInteger() {\n" +
				"\t\treturn "+imageType.isInteger()+";\n" +
				"\t}\n" +
				"\n" +
				"\tpublic "+sumType+" get(int i) {\n" +
				"\t\treturn data[i];\n" +
				"\t}\n" +
				"\n" +
				"\tpublic "+sumType+" computeSum() {\n" +
				"\t\t"+sumType+" sum = 0;\n" +
				"\t\tfor( int i = 0; i < data.length; i++ ) {\n" +
				"\t\t\tsum += data[i];\n" +
				"\t\t}\n" +
				"\n" +
				"\t\treturn sum;\n" +
				"\t}\n" +
				"\n" +
				"\tpublic "+sumType+"[] getData() {\n" +
				"\t\treturn data;\n" +
				"\t}\n" +
				"\n" +
				"\tpublic void print() {\n" +
				"\t\tfor (int i = 0; i < width; i++) {\n");
		if( imageType.isInteger() )
				out.print("\t\t\tSystem.out.printf(\"%6d \", data[i]);\n");
		else if( imageType.isInteger() )
			out.print("\t\t\tSystem.out.printf(\"%6.3f \", data[i]);\n");

		out.print("\t\t}\n" +
				"\t\tSystem.out.println();\n" +
				"\t}\n" +
				"}\n\n");

	}

	public static void main( String args[] ) throws FileNotFoundException {
		GenerateKernel1D app = new GenerateKernel1D();
		app.generate();
	}
}
